package ni;

import java.net.*;

import main.ChatNI;

/**
 * Abstract class implemented by UdpReceiver and UdpSender
 * Contains the commons fields and methods
 * Package  ni
 * Project ChatSystemG5 - INSA 4INFOA1 - 2013/2014
 * @author Thomas Vuillemin Martin Conant
 */
public abstract class Udp extends Thread {
	
	protected int port;
	protected DatagramSocket socket;
	protected ChatNI ni;
	
	/**
	 * Basic constructor
	 * @param ni the ChatNI object
	 */
	public Udp(ChatNI ni){
		this.ni=ni;
	}

	/**
	 * get the ni parameter
	 * @return the ChatNI
	 */
	public ChatNI getNi() {
		return ni;
	}

	/**
	 * set the ni field
	 * @param ni the ChatNI to be set
	 */
	public void setNi(ChatNI ni) {
		this.ni = ni;
	}

	/**
	 * Open a DatagramSocket on a specified port
	 * @param port the port on which the socket need to be open
	 */
	protected void openUdpSocket(int port) {
		
		this.port = port;		
		try {
			socket = new DatagramSocket(port);
			System.out.println("Could open an udp socket on port : " + port);
			
		} catch (SocketException e) {
			System.out.println("Could not open an udp socket on port : " + port);
		}
	}
	
	/**
	 * Close the socket associated to the object
	 */
	public void closeSocket() {
		
		if (this.socket != null) {
			this.socket.close();
		} else {
			System.out.println("Aucun socket actif");
		}
	}
	
	/**
	 * Calculate the broadcast address of a specified InetAddress
	 * @param address the InetAdress on which the broadcast address will be calculated
	 * @return the broadcast address calculated
	 */
	public InetAddress getBroadcastAddress(InetAddress address)
	{
		String firstIpNumber = address.getHostAddress().substring(0, 1);
		String threefirstIpNumbers = address.getHostAddress().substring(0, 3);
		String broadcast = "0.0.0.0";
		
		int i=0;
		while(!address.getHostAddress().substring(i, i+1).equals("."))
		{
			i++;
		}
		String firstIpNumbers = address.getHostAddress().substring(0, i);
		//System.out.println("First numbers : " + firstIpNumbers);
		
		if(Integer.parseInt(firstIpNumbers) < 128) 
		{
			//System.out.println("Addresse IP locale de classe A");
			int j = 0;
			for (i=0 ; i<1 ; i++){		
				while(address.getHostAddress().charAt(j) != '.')
				{
					j++;
				}
				j++;
			}
			
			broadcast = address.getHostAddress().substring(0, j) + "255.255.255";
		}
		else if (Integer.parseInt(firstIpNumbers) < 192)
		{	
			//System.out.println("Addresse IP locale de classe B");
			
			int j = 0;
			for (i=0 ; i<2 ; i++){		
				while(address.getHostAddress().charAt(j) != '.')
				{
					j++;
				}
				j++;
			}
			
			broadcast = address.getHostAddress().substring(0, j) + "255.255";
		}
		else if (Integer.parseInt(firstIpNumbers) < 224) 
		{
			//System.out.println("Addresse IP locale de classe C");
			
			int j = 0;
			for (i=0 ; i<3 ; i++){		
				while(address.getHostAddress().charAt(j) != '.')
				{
					j++;
				}
				j++;
			}
			
			broadcast = address.getHostAddress().substring(0, j) + "255";
		}
		
		//System.out.println("Addresse de broadcast : " + broadcast);
		
		try {
			address = InetAddress.getByName(broadcast);
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return address;
		
	}
	
	/**
	 * Get the field port
	 * @return the port associated to this object
	 */
	public int getPort()
	{
		return this.port;
	}
	
	/**
	 * Get the socket field
	 * @return the DatagramSocket associated to this object
	 */
	public DatagramSocket getSocket()
	{
		return this.socket;
	}
	
	/**
	 * Abstract run method.
	 * Will be implemented by udpReceiver and udpSender
	 */
	public abstract void run();
	
}